/*--------------------------------------------------------------------------
 DEPUI-GFX-TK 3.0 - GPL portable source code libraries 
 http://www.deleveld.dds.nl/depui.htm
 See file docs/copying for copyright details
 ---------------------------------------------------------------------------*/

#define MXMODULE_SYSMENU
#include "depui/depui.c"

typedef struct MYOBJ {
	union {
		MX_OBJ_DATA obj;
		MX_RECTATOM_DATA rectatom;
		MX_ATOM atom;
	} base;
	MX_TEXTUAL message;
} MYOBJ;

static void myobj_class(void)
{
	switch (mx.event) {

	case MX_POINTER_MOVE:{

			/* Find out if the button is down or not */
			const MX_POINTER_INFO *info = mx_pointer_info();

			if ((info) && (info->b)) {

				/* Find out the old position */
				const int x = mx_x(mx.obj);
				const int y = mx_y(mx.obj);

				/* How much has the pointer moved */
				const int dx = info->dx;
				const int dy = info->dy;

				/* Reposition the object, marking cahnged areas for redraw */
				mx_dirty(mx.obj, true);
				mx_move(mx.obj, x + dx, y + dy);
				mx_dirty(mx.obj, true);
			}
			break;
		}

	default:
		break;
	}

	mx_obj_class();
}

static MYOBJ *newobj(void)
{
	MYOBJ *obj = mx_obj((MX_OBJ *)0, myobj_class, sizeof(MYOBJ), (MX_OBJ *)0, 0);

	if (obj) {
		/* We need to accept pointer move events */
		mx_wantmove(obj, true);

		/* Make the message a child of the object */
		mx_textual(&obj->message, 0, obj, 0);
		mx_text_set(&obj->message, "Dragable object", -1, 0);
		mx_move(&obj->message, 5, 5);
		mx_defaultrect(&obj->message, 0);
		mx_wantpointer(obj, true);
	}
	return obj;
}

int main(int argc, char *argv[])
{
	MYOBJ *myobj;

	(void) argc;
	(void) argv;

	if (!mx_start())
		return EXIT_FAILURE;

	mx_sysmenu();

	myobj = newobj();
	assert(myobj);

	mx_position(myobj, 50, 50, 150, 50);

	return mx_execute();
}
